#include "NodeOutPort.h"
#include "AbstractShapeItem.h"
#include "NodeItem.h"
#include "DiagramScene.h"
#include "AbstractMappingWindow.h"
#include "LineItem.h"
#include "xOutMappingPort.h"
#include "AbstractManager.h"
#include "NodeInPort.h"
#include <QPainter>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsScene>

namespace {
	const static int TYPE_BLOCK_RIGHT_PADDING = 4;
	const static int TYPE_BLOCK_LEFT_PADDING = 4;
	const static int LEFT_PADDING = 4;
	const static int TOP_PADDING = 0;
}

NodeOutPort::NodeOutPort(xOutMappingPort* outport, AbstractShapeItem* parent)
	:NodePort(parent)
{
	this->_parent = parent;
	this->_outport = outport; 
	this->_name = this->_outport->getName();
	this->_portIOType = NodePort::OUTPORT;
	this->setPen(QPen(QBrush(Qt::white), 3));
	this->_x = ( _parent->width() * 1) - NodePort::RADIUS;
	this->setPortInitVisible();
	this->drawName_ = false;
}

NodeOutPort::~NodeOutPort(void)
{
}

void NodeOutPort::paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
	QFont sansFont("Helvetica", 8);
	QFontMetrics fontMetrics(sansFont);
	int typeBlockWidth = fontMetrics.width(this->_outport->getType().c_str()) + TYPE_BLOCK_LEFT_PADDING + TYPE_BLOCK_RIGHT_PADDING;
	int typeBlockHeight = fontMetrics.height();

	// 假如是 GateItem 的 outport，則改畫成下面的形狀
	if ( this->_parent->nodeType() == AbstractShapeItem::GATE_NODE) {

		painter->setBrush(QBrush(QColor("#333333")));
		painter->setPen(QPen(QColor("#FFFFFF")));

		QImage outputImage(":/resource/outport.png");
		painter->drawEllipse( this->_x, this->_y, NodePort::GATE_RADIUS*2, NodePort::GATE_RADIUS*2 );
		painter->drawImage( this->_x + GATE_RADIUS, this->_y + GATE_RADIUS / 2, outputImage );

		// 畫 Item type block 跟 type 名稱
#if 0
		if( this->drawName_ ) {
			painter->setPen(QPen(Qt::NoPen));
			painter->setBrush(QBrush(QColor("#575757")));
			painter->drawRoundedRect( LEFT_PADDING , this->_y + TOP_PADDING, typeBlockWidth, typeBlockHeight, 2 ,2);

			painter->setPen(QPen(QColor("#FFFFFF")));
			painter->setFont(sansFont);
			painter->drawText( LEFT_PADDING, this->_y + TOP_PADDING, typeBlockWidth, typeBlockHeight, Qt::AlignCenter, trf(this->_outport->getType()).c_str());
		}
#endif

		return;
	}

	painter->setBrush(QBrush(QColor("#333333")));
	painter->setPen(this->pen());

	painter->drawEllipse(this->_x, this->_y, NodePort::RADIUS*2, NodePort::RADIUS*2);

	if ( !this->_portLineList.empty() )
	{
		QPointF center( this->_x+ NodePort::RADIUS, this->_y+ NodePort::RADIUS );
		painter->setBrush(QBrush(Qt::white));
		painter->drawEllipse( center, 2, 2);
	}

	if( this->drawName_ ) {
		// 繪製port name
		painter->setFont(sansFont);
		painter->setPen(QPen(Qt::white));
		if( this->_parent->nodeType() == AbstractShapeItem::ENTRY_NODE ) {
			painter->drawText( 20, this->_y,100,20, Qt::AlignLeft, trf(_name).c_str());
		} else {
			painter->drawText( this->_x + 20, this->_y,100,20, Qt::AlignLeft, trf(_name).c_str());
		}

		// 畫 Item type block 跟 type 名稱
		painter->setPen(QPen(Qt::NoPen));
		painter->setBrush(QBrush(QColor("#575757")));
		if( this->_parent->nodeType() == AbstractShapeItem::ENTRY_NODE ) {
			painter->drawRoundedRect( LEFT_PADDING , this->_y + TOP_PADDING, typeBlockWidth, typeBlockHeight, 0, 0 );
		} else {
			painter->drawRoundedRect( this->_x - 30 - LEFT_PADDING , this->_y + TOP_PADDING, typeBlockWidth, typeBlockHeight, 2 ,2);
		}

		painter->setPen(QPen(QColor("#FFFFFF")));
		painter->setFont(sansFont);
		if( this->_parent->nodeType() == AbstractShapeItem::ENTRY_NODE ) {
			painter->drawText( LEFT_PADDING, this->_y + TOP_PADDING, typeBlockWidth, typeBlockHeight, Qt::AlignCenter, trf(this->_outport->getType()).c_str());
		} else {
			painter->drawText( this->_x - 30 - LEFT_PADDING, this->_y + TOP_PADDING, typeBlockWidth, typeBlockHeight, Qt::AlignCenter, trf(this->_outport->getType()).c_str());
		}
	}
}

QRectF NodeOutPort::boundingRect() const
{
	return QRectF( this->_x,this->_y,115,15 );
}

int NodeOutPort::getClass()
{
	assert(this->_outport);
	return this->_outport->getClass();
}

int NodeOutPort::getCategory()
{
	assert(this->_outport);
	return this->_outport->getCategory();
}

void NodeOutPort::mouseReleaseEvent( QGraphicsSceneMouseEvent* event)
{
	DiagramScene* scene = this->_parent->getManager()->getMappingDialog()->currentScene();

	if ( event->button() == Qt::LeftButton ) {
		AbstractManager* manager = this->_parent->getManager();
		NodePort* releasePort = manager->getCollidePort(event->scenePos());

		if ( releasePort!=NULL && manager->verifyLink(this, releasePort)) {
			NodeInPort* inport = dynamic_cast< NodeInPort* >( releasePort );
			if (inport->getParent()->getName() == "terminal") {
				inport->setBrush(QBrush(Qt::white));
			} else {
				inport->setBrush(QBrush("#333333"));
			}
			LineItem* newLine = manager->createLine(inport, this);
			scene->addItem(newLine);

			// 假如目的 node inport的個數是可變動的(像是vmcollector)，則當新的link產生時要增加一個新port
			if ( inport->getParent()->getName() != "terminal")
			{
				if (!inport->getParent()->getMappingNode()->getNodeTypePtr()->getInportFixed()) {
					inport->getParent()->addInPort();
				}
				if (!this->getParent()->getMappingNode()->getNodeTypePtr()->getOutportFixed()) {
					this->getParent()->addOutPort();
				}
			}
		} 
	} 

	this->scene()->removeItem(_line);
	_line = NULL;
}

xOutMappingPort* NodeOutPort::getOutport()
{
	return this->_outport;
}

void NodeOutPort::setDrawName( bool drawName ) {
	this->drawName_ = drawName;
}
